// main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "linenoise.h"
#include <atomic>
#include <iostream>
#include "linenoise_cmd.h"
// 环境变量存储（简单哈希表替代）
#define MAX_ENVS 32
#define MAX_ENV_NAME 32
#define MAX_ENV_VALUE 128

typedef struct
{
    char name[MAX_ENV_NAME];
    char value[MAX_ENV_VALUE];
} env_t;

env_t envs[MAX_ENVS];
int env_count = 0;

// 函数声明
int cmd_help(int argc, char *argv[]);
int cmd_echo(int argc, char *argv[]);
int cmd_setenv(int argc, char *argv[]);
int cmd_printenv(int argc, char *argv[]);
int cmd_exit(int argc, char *argv[]);

// 命令表
typedef int (*command_func_t)(int, char **);

struct command
{
    const char *name;
    command_func_t func;
    const char *help;
};

struct command commands[] = {
    {"help", cmd_help, "Show available commands"},
    {"echo", cmd_echo, "Print arguments"},
    {"setenv", cmd_setenv, "Set environment variable: setenv NAME value"},
    {"printenv", cmd_printenv, "Print all environment variables"},
    {"exit", cmd_exit, "Exit the shell"},
    {"push_base", cmd_test_push_base, "auto_push_base"},
    {"push_value", cmd_test_push_value, "cmd_test_push_value"},
    {NULL, NULL, NULL}};

// 查找环境变量
char *my_getenv(const char *name)
{
    for (int i = 0; i < env_count; i++)
    {
        if (strcmp(envs[i].name, name) == 0)
        {
            return envs[i].value;
        }
    }
    return NULL;
}

// 设置环境变量
int my_setenv(const char *name, const char *value)
{
    // 检查是否已存在
    for (int i = 0; i < env_count; i++)
    {
        if (strcmp(envs[i].name, name) == 0)
        {
            strncpy(envs[i].value, value, MAX_ENV_VALUE - 1);
            return 0;
        }
    }
    // 新增
    if (env_count < MAX_ENVS)
    {
        strncpy(envs[env_count].name, name, MAX_ENV_NAME - 1);
        strncpy(envs[env_count].value, value, MAX_ENV_VALUE - 1);
        env_count++;
        return 0;
    }
    return -1;
}

// 命令实现
int cmd_help(int argc, char *argv[])
{
    printf("Available commands:\n");
    for (int i = 0; commands[i].name; i++)
    {
        printf("  %-10s - %s\n", commands[i].name, commands[i].help);
    }
    return 0;
}

int cmd_echo(int argc, char *argv[])
{
    for (int i = 1; i < argc; i++)
    {
        // 支持 $VAR 替换
        if (argv[i][0] == '$')
        {
            char *val = my_getenv(argv[i] + 1);
            printf("%s ", val ? val : "");
        }
        else
        {
            printf("%s ", argv[i]);
        }
    }
    printf("\n");
    return 0;
}

int cmd_setenv(int argc, char *argv[])
{
    if (argc != 3)
    {
        printf("Usage: setenv NAME value\n");
        return -1;
    }
    my_setenv(argv[1], argv[2]);
    printf("Set: %s=%s\n", argv[1], argv[2]);
    return 0;
}

int cmd_printenv(int argc, char *argv[])
{
    for (int i = 0; i < env_count; i++)
    {
        printf("%s=%s\n", envs[i].name, envs[i].value);
    }
    return 0;
}

int cmd_exit(int argc, char *argv[])
{
    printf("Goodbye!\n");
    exit(0);
    return 0;
}

// Tab 补全
void completion(const char *buf, linenoiseCompletions *lc)
{
    char var[256];
    // 补全命令
    for (int i = 0; commands[i].name; i++)
    {
        if (strncmp(buf, commands[i].name, strlen(buf)) == 0)
        {
            linenoiseAddCompletion(lc, commands[i].name);
        }
    }
    // 补全环境变量（如输入 $U 则补全 $USER）
    if (buf[0] == '$')
    {
        for (int i = 0; i < env_count; i++)
        {

            snprintf(var, sizeof(var), "$%s", envs[i].name);
            if (strncmp(buf, var, strlen(buf)) == 0)
            {
                linenoiseAddCompletion(lc, var);
            }
        }
    }
}

// 简单解析命令行
int parse_line(char *line, char *argv[])
{
    int argc = 0;
    char *p = line;

    while (*p)
    {
        while (*p == ' ' || *p == '\t')
            p++;
        if (*p && *p != '#')
        {
            argv[argc++] = p;
            while (*p && *p != ' ' && *p != '\t')
                p++;
            if (*p)
                *p++ = '\0';
        }
    }
    argv[argc] = NULL;
    return argc;
}
static std::atomic<bool> s_stop(false);
void set_linenoise_stop_flag(bool stop)
{
    s_stop = stop;
}

int linenoise_run(void)
{
    char *line;

    // 初始化默认环境变量
    my_setenv("USER", "root");
    my_setenv("SHELL", "myshell");

    // 加载历史
    linenoiseHistoryLoad("shell_history.txt");
    linenoiseHistorySetMaxLen(100);

    // 设置补全回调
    linenoiseSetCompletionCallback(completion);

    printf("Embedded Shell Test (using linenoise)\n");
    printf("Type 'help' for commands. Press Ctrl+C to exit.\n\n");

    while (!s_stop && (line = linenoise("shell> ")) != NULL)
    {
        if (line[0] == '\0')
        {
            free(line);
            continue;
        }

        // 添加到历史
        linenoiseHistoryAdd(line);

        // 解析命令
        char *argv[64];
        int argc = parse_line(line, argv);

        if (argc > 0)
        {
            int found = 0;
            for (int i = 0; commands[i].name; i++)
            {
                if (strcmp(argv[0], commands[i].name) == 0)
                {
                    commands[i].func(argc, argv);
                    found = 1;
                    break;
                }
            }
            if (!found)
            {
                printf("Command not found: %s\n", argv[0]);
            }
        }

        free(line);
    }

    // 保存历史
    linenoiseHistorySave("shell_history.txt");

    return 0;
}